//
//  ViewControlProtocol.swift
//  CooperSwift_Example
//
//  Created by 计海峰 on 2021/10/14.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import Foundation
import UIKit
import WebKit

// MARK: - 动态绑定key
private struct AssociateKeys {
    // MARK: - base 约束
    static var margin: Void?
    static var padding: Void?
    // MARK: - base 属性
    static var frame: Void?
    
    static var isHidden: Void?
    static var isShow: Void?
    
    static var bgColor: Void?
    static var tag: Void?
    
    static var vRadius: Void?
    static var cornerRadii: Void?
    static var masksToBounds: Void?
    
    // MARK: - image
    static var url: Void?
    static var imageName: Void?
    static var imageSource: Void?
    static var placeholderImage: Void?
    static var contentMode: Void?
    
    // MARK: - label
    static var text: Void?
    static var textColor: Void?
    static var font: Void?
    static var lines: Void?
    static var textAlignment: Void?
    
    static var attributed: Void?
    static var method: Void?
    
    // MARK: - web
    static var baseUrl: Void?
}

// MARK: - ViewControlProtocol 一些view的基础约束 一般特殊实现 以及特殊view 的 特殊资源
public protocol ViewControlProtocol: AssociatedObjectStore { }

public extension ViewControlProtocol {
    
    // MARK: - base 约束
    var margin: UIEdgeInsets { ///  外边距
        get {
            return associatedObject(forKey: &AssociateKeys.margin, default: .zero, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.margin, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var padding: UIEdgeInsets { ///  内边距
        get {
            return associatedObject(forKey: &AssociateKeys.padding, default: .zero, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.padding, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - base 属性
    var frame: CGRect { /// 所在父组件位置和大小
        get {
            return associatedObject(forKey: &AssociateKeys.frame, default: .zero, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.frame, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var isHidden: Bool { /// 是否隐藏
        get {
            return associatedObject(forKey: &AssociateKeys.isHidden, default: false, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.isHidden, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var isShow: Bool { /// 是否显示
        get {
            return associatedObject(forKey: &AssociateKeys.isShow, default: true, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.isShow, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var bgColor: UIColor? { /// 圆角
        get {
            return associatedObject(forKey: &AssociateKeys.bgColor, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.bgColor, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var tag: Int? { /// tag
        get {
            return associatedObject(forKey: &AssociateKeys.tag, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.tag, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var masksToBounds: Bool? { /// 切边
        get {
            return associatedObject(forKey: &AssociateKeys.masksToBounds, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.masksToBounds, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var vRadius: CGFloat? { /// 圆角
        get {
            return associatedObject(forKey: &AssociateKeys.vRadius, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.vRadius, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var cornerRadii: UIView.CornerRadii? { /// 圆角
        get {
            return associatedObject(forKey: &AssociateKeys.cornerRadii, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.cornerRadii, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - image
    var url: String? { /// 路径
        get {
            return associatedObject(forKey: &AssociateKeys.url, default: nil, ploicy: .OBJC_ASSOCIATION_COPY)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.url, ploicy: .OBJC_ASSOCIATION_COPY)
        }
    }
    
    var imageName: String? { /// 图片名字
        get {
            return associatedObject(forKey: &AssociateKeys.imageName, default: nil, ploicy: .OBJC_ASSOCIATION_COPY)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.imageName, ploicy: .OBJC_ASSOCIATION_COPY)
        }
    }
    
    var imageSource: UIImage? { /// 图片资源
        get {
            return associatedObject(forKey: &AssociateKeys.imageSource, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.imageSource, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var placeholderImage: UIImage { /// 占位图
        get {
            return associatedObject(forKey: &AssociateKeys.placeholderImage, default: .init(color: .init(hex: "f3f4f5"), size: CGSize(1, 1)), ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.placeholderImage, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - label
    
    var attributed: NSAttributedString? { /// 富文本
        get {
            return associatedObject(forKey: &AssociateKeys.attributed, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.attributed, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - label & button
    var text: String? { /// 文本内容
        get {
            return associatedObject(forKey: &AssociateKeys.text, default: nil, ploicy: .OBJC_ASSOCIATION_COPY)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.text, ploicy: .OBJC_ASSOCIATION_COPY)
        }
    }
    
    var textColor: UIColor? { /// 字体颜色
        get {
            return associatedObject(forKey: &AssociateKeys.textColor, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.textColor, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var font: UIFont? { /// 字号
        get {
            return associatedObject(forKey: &AssociateKeys.font, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.font, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var lines: Int { /// 行数
        get {
            return associatedObject(forKey: &AssociateKeys.lines, default: 1, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.lines, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    var textAlignment: NSTextAlignment? { /// 对齐方式
        get {
            return associatedObject(forKey: &AssociateKeys.textAlignment, default: nil, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.textAlignment, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
    // MARK: - button
    var method: String? { /// 方法
        get {
            return associatedObject(forKey: &AssociateKeys.method, default: nil, ploicy: .OBJC_ASSOCIATION_COPY)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.method, ploicy: .OBJC_ASSOCIATION_COPY)
        }
    }
    
    // MARK: - web view
    var baseUrl: String? { /// 路径
        get {
            return associatedObject(forKey: &AssociateKeys.baseUrl, default: nil, ploicy: .OBJC_ASSOCIATION_COPY)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.baseUrl, ploicy: .OBJC_ASSOCIATION_COPY)
        }
    }
    
    var contentMode: UIView.ContentMode {
        get {
            return associatedObject(forKey: &AssociateKeys.contentMode, default: .scaleAspectFill, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
        set {
            setAssociatedObject(newValue, forKey: &AssociateKeys.contentMode, ploicy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }
    
}


// MARK: - view
public extension ViewControlProtocol {
//    /// to default
//    func loadDefault(_ target: UIView) {
//        target.addCorner(.init(0))
//    }
    
    /// 加载frame
    func loadFrame(_ target: UIView) {
        if frame.isZero() { return }
        target.frame = frame
    }

    /// 加载背景色
    func loadBgColor(_ target: UIView) {
        guard let color = self.bgColor else { return }
        target.backgroundColor = color
    }
    /// 加载圆角
    func loadRadius(_ target: UIView) {
        guard let radius = self.vRadius else { return }
        target.addCorner(UIView.CornerRadii(radius))
    }
    func loadCornerRadii(_ target: UIView) {
        guard let radius = self.cornerRadii else { return }
        target.addCorner(radius)
    }
    
    /// 切边
    func loadMasksToBounds(_ target: UIView) {
        guard let masksToBounds = self.masksToBounds else { return }
        target.layer.masksToBounds = masksToBounds
    }
    
    //MARK: - 加载图片
    @MainActor func loadImageUrl(_ imageView: UIImageView) {
        imageView.contentMode = .scaleAspectFill
        if let path = self.url {
            imageView.kf.setImage(with: URL(string: path), placeholder: self.placeholderImage, options: nil)
        }
        if let image = self.imageSource {
            imageView.image = image
        }
        if let name = self.imageName , let source = UIImage.init(named: name) {
            imageView.image = source
        }
    }
    
    //MARK: - 加载label
    func loadLabel(_ lb: UILabel) {
        if let text = self.text {
            lb.text = text
        }
        if let font = self.font {
            lb.font = font
        }
        if let color = self.textColor {
            lb.textColor = color
        }
        if let textAlignment = self.textAlignment {
            lb.textAlignment = textAlignment
        }
        if let attributed = self.attributed {
            lb.attributedText = attributed
        }
    }
    
    //MARK: - 加载button
    @MainActor func loadButton(_ btn: UIButton) {
        if let text = self.text {
            btn.setTitle(text, for: .normal)
        }
        if let font = self.font {
            btn.titleLabel?.font = font
        }
        if let color = self.textColor {
            btn.setTitleColor(color, for: .normal)
        }
        if let path = self.url {
            btn.kf.setImage(with: URL(string: path), for: .normal, placeholder: self.placeholderImage)
        }
        if let image = self.imageSource {
            btn.setImage(image, for: .normal)
        }
        if let name = self.imageName , let image = UIImage.init(named: name) {
            btn.setImage(image, for: .normal)
        }
    }
    
    //MARK: - 加载web
    func loadWebView(_ web: WKWebView) {
        if let text = self.text {
            if let base = baseUrl {
                web.loadHTMLString(text, baseURL: URL.init(string: base))
                return
            }
            web.loadHTMLString(text, baseURL: nil)
            return
        }
        if let url = self.url {
            guard let request = URLRequest.init(urlString: url) else { return }
            web.load(request)
            return
        }
    }
    
    //MARK: - 加载全部
    @MainActor func loadAll<T: UIView>(_ target: T, judgeType: Bool = true) {
        target.isHidden = isHidden
        if let viewTag = tag {
            target.tag = viewTag
        }
        if isHidden { return }
        loadFrame(target)
        loadBgColor(target)
        loadCornerRadii(target)
        loadMasksToBounds(target)
        loadRadius(target)
        if judgeType {
            if let imageView = target as? UIImageView {
                loadImageUrl(imageView)
            }
            if let lb = target as? UILabel {
                loadLabel(lb)
            }
            if let btn = target as? UIButton {
                loadButton(btn)
            }
            if let web = target as? WKWebView {
                loadWebView(web)
            }
        }
    }
    
}
